﻿using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using RaytracerLib.Layers;
using RaytracerLib.MathLib;
using TomanuExtensions;
using RaytracerLib;
using RaytracerLib.Layers.OverlayCorrectors;
using RaytracerLib.Layers.Interpolators;
using YAXLib;

namespace RaytracerTest
{
    [TestClass]
    public class ArraysTest : TestBase
    {
        [TestMethod]
        public void Arrays_Test()
        {
            Arrays_Overshoot();
            Arrays_GetArrayRect();
            Arrays_Xml();
            Arrays_Equals();
            Arrays_SetX_GetBitmap_GetArray();
            Arrays_Create();
            Arrays_Draw();
        }

        public void Arrays_GetArrayRect()
        {
            {
                ColorArrayFloat ar1 = new ColorArrayFloat(10, 13);
                ColorArrayFloat ar2 = new ColorArrayFloat(13, 17);

                int v = 1;

                for (int x = 0; x < 0 + 5; x++)
                {
                    for (int y = 0; y < 0 + 7; y++)
                    {
                        ar1.SetColor(x, y,
                            new ColorFloat(v++ / 255.0, v++ / 255.0, v++ / 255.0));
                    }
                }

                ar2 = ar1.GetArrayRect(new Rectangle(0, 0, 5, 7));

                for (int x = 0; x < 0 + 5; x++)
                {
                    for (int y = 0; y < 0 + 7; y++)
                        Assert.IsTrue(ar1.GetColor(x, y).IsAlmostRelativeEquals(ar2.GetColor(x, y)));
                }
            }

            {
                ValueArrayFloat ar1 = new ValueArrayFloat(10, 13);
                ValueArrayFloat ar2 = new ValueArrayFloat(13, 17);

                int v = 1;

                for (int x = 0; x < 0 + 5; x++)
                {
                    for (int y = 0; y < 0 + 7; y++)
                        ar1.SetValue(x, y, v++ / 255.0);
                }

                ar2 = ar1.GetArrayRect(new Rectangle(0, 0, 5, 7));

                for (int x = 0; x < 0 + 5; x++)
                {
                    for (int y = 0; y < 0 + 7; y++)
                        Assert.IsTrue(ar1.GetValue(x, y).IsAlmostRelativeEquals(ar2.GetValue(x, y)));
                }
            }
        }

        public void Arrays_Overshoot()
        {
            {
                ColorArrayFloat ar1 = new ColorArrayFloat(10, 10);

                ColorFloat b1 = new ColorFloat(-1.2, 0, 1);
                ColorFloat b2 = new ColorFloat(1.2, 0, 1);

                ar1[0, 0] = b1;
                ar1[0, 1] = b2;

                ColorFloat c1 = ar1.GetColor(0, 0);
                ColorFloat c2 = ar1.GetColor(0, 1);

                Assert.AreEqual(c1, b1);
                Assert.AreEqual(c2, b2);

                {
                    ColorArrayFloat ar2 = ar1.GetArrayRect(new Rectangle(0, 0, 10, 10));

                    c1 = ar2.GetColor(0, 0);
                    c2 = ar2.GetColor(0, 1);

                    Assert.AreEqual(c1, b1);
                    Assert.AreEqual(c2, b2);
                }

                {
                    ColorArrayFloat ar2 = new ColorArrayFloat(10, 10);
                    ar2.Draw(ar1, new Rectangle(0, 0, 10, 10), new Rectangle(0, 0, 10, 10));

                    c1 = ar2.GetColor(0, 0);
                    c2 = ar2.GetColor(0, 1);

                    Assert.AreEqual(c1, b1);
                    Assert.AreEqual(c2, b2);
                }
            }

            {
                ValueArrayFloat ar1 = new ValueArrayFloat(10, 10);

                ar1[0, 0] = 0;
                ar1[0, 1] = 1;
                ar1[0, 2] = 1.2;
                ar1[0, 3] = -1.2;

                Assert.AreEqual(ar1[0, 0], 0);
                Assert.AreEqual(ar1[0, 1], 1);
                Assert.IsTrue(ar1[0, 2].IsAlmostEquals(1.2, Constants.FLOAT_PRECISION));
                Assert.AreEqual(ar1[0, 3], -1.2, Constants.FLOAT_PRECISION);
            }
        }

        public void Arrays_Xml()
        {
            string file = "small_for_test1.bmp";

            {
                ColorArrayFloatFile x1 = new ColorArrayFloatFile(file, a_overlayMethod: OverlayMethod.Edge, a_interpolationMethod: InterpolationMethod.NearestNeighbour);

                var xml1 = YAXSerializer.SerializeToString(x1);

                ColorArrayFloatFile x2 =
                    YAXSerializer.DeserializeFromString<ColorArrayFloatFile>(xml1);

                Assert.IsTrue(x1.Equals(x2));

                var xml2 = YAXSerializer.SerializeToString(x2);

                Assert.AreEqual(xml1.ToString(), xml2.ToString());
            }
            {
                ValueArrayFloatFile x1 = new ValueArrayFloatFile(file, OverlayMethod.Edge,
                    InterpolationMethod.NearestNeighbour);

                var xml1 = YAXSerializer.SerializeToString(x1);

                ValueArrayFloatFile x2 =
                    YAXSerializer.DeserializeFromString<ValueArrayFloatFile>(xml1);

                Assert.IsTrue(x1.Equals(x2));

                var xml2 = YAXSerializer.SerializeToString(x2);

                Assert.AreEqual(xml1.ToString(), xml2.ToString());
            }
        }

        public void Arrays_Draw()
        {
            {
                ColorArrayFloat ar1 = new ColorArrayFloat(10, 13);
                ColorArrayFloat ar2 = new ColorArrayFloat(13, 17);

                int v = 1;

                for (int x = 0; x < 0 + 5; x++)
                {
                    for (int y = 0; y < 0 + 7; y++)
                    {
                        ar1.SetColor(x, y,
                            new ColorFloat(v++ / 255.0, v++ / 255.0, v++ / 255.0));
                    }
                }

                ar2.Draw(ar1, new Rectangle(0, 0, 5, 7),
                    new Rectangle(0, 0, 5, 7));

                for (int x = 0; x < 0 + 5; x++)
                {
                    for (int y = 0; y < 0 + 7; y++)
                        Assert.IsTrue(ar1.GetColor(x, y).IsAlmostRelativeEquals(ar2.GetColor(x, y)));
                }
            }

            {
                ColorArrayFloat ar1 = new ColorArrayFloat(10, 13);
                ColorArrayFloat ar2 = new ColorArrayFloat(13, 17);

                int v = 1;

                for (int x = 5; x < 5 + 5; x++)
                {
                    for (int y = 6; y < 6 + 7; y++)
                    {
                        ar1.SetColor(x, y,
                            new ColorFloat(v++ / 255.0, v++ / 255.0, v++ / 255.0));
                    }
                }

                ar2.Draw(ar1, new Rectangle(5, 6, 5, 7),
                    new Rectangle(8, 10, 5, 7));

                for (int x = 8; x < 8 + 5; x++)
                {
                    for (int y = 10; y < 10 + 7; y++)
                    {
                        Assert.IsTrue(ar1.GetColor(x - 3, y - 4).IsAlmostRelativeEquals(
                            ar2.GetColor(x, y)));
                    }
                }
            }
        }

        public void Arrays_Equals()
        {
            {
                ColorArrayFloat x1 = new ColorArrayFloat(20, 20);
                ColorArrayFloat x2 = new ColorArrayFloat(20, 20);

                Assert.IsTrue(x1.Equals(x2));
                Assert.IsTrue(x1.IsAlmostRelativeEquals(x2));

                x1.SetColor(0, 0, new ColorFloat(0.5));
                x2.SetColor(0, 0, new ColorFloat(0.5 - 0.5 * Constants.COLOR_PRECISION / 2));

                Assert.IsTrue(!x1.Equals(x2));
                Assert.IsTrue(x1.IsAlmostRelativeEquals(x2));

                x1.SetColor(0, 0, new ColorFloat(0.5));
                x2.SetColor(0, 0, new ColorFloat(0.5 - 0.5 * Constants.COLOR_PRECISION));

                Assert.IsTrue(!x1.Equals(x2));
                Assert.IsTrue(!x1.IsAlmostRelativeEquals(x2));
            }

            {
                ValueArrayFloat x1 = new ValueArrayFloat(20, 20);
                ValueArrayFloat x2 = new ValueArrayFloat(20, 20);

                Assert.IsTrue(x1.Equals(x2));
                Assert.IsTrue(x1.IsAlmostRelativeEquals(x2));

                x1.SetValue(0, 0, 0.3);

                Assert.IsTrue(!x1.Equals(x2));
                Assert.IsTrue(!x1.IsAlmostRelativeEquals(x2));

                x2.SetValue(0, 0, 0.3);

                Assert.IsTrue(x1.Equals(x2));
                Assert.IsTrue(x1.IsAlmostRelativeEquals(x2));

                x1.SetValue(x1.Width - 1, x1.Height - 1, 0.3);

                Assert.IsTrue(!x1.Equals(x2));
                Assert.IsTrue(!x1.IsAlmostRelativeEquals(x2));

                x2.SetValue(x1.Width - 1, x1.Height - 1, 0.3);

                Assert.IsTrue(x1.Equals(x2));
                Assert.IsTrue(x1.IsAlmostRelativeEquals(x2));

                x1.SetValue(0, 0, 0.5);
                x2.SetValue(0, 0, 0.5 - 0.5 * Constants.COLOR_PRECISION / 2);

                Assert.IsTrue(!x1.Equals(x2));
                Assert.IsTrue(x1.IsAlmostRelativeEquals(x2));

                x1.SetValue(0, 0, 0.5);
                x2.SetValue(0, 0, 0.5 - 0.5 * Constants.COLOR_PRECISION);

                Assert.IsTrue(!x1.Equals(x2));
                Assert.IsTrue(!x1.IsAlmostRelativeEquals(x2));
            }

            {
                {
                    var x1 = new ColorArrayFloat(100, 100, OverlayMethod.Edge,
                        InterpolationMethod.NearestNeighbour);
                    var x2 = new ColorArrayFloat(100, 100, OverlayMethod.Edge,
                        InterpolationMethod.NearestNeighbour);

                    Assert.AreEqual(x1, x2);
                }
                {
                    var x1 = new ColorArrayFloat(99, 100, OverlayMethod.Edge,
                        InterpolationMethod.NearestNeighbour);
                    var x2 = new ColorArrayFloat(100, 100, OverlayMethod.Edge,
                        InterpolationMethod.NearestNeighbour);

                    Assert.AreNotEqual(x1, x2);
                }
                {
                    var x1 = new ColorArrayFloat(100, 99, OverlayMethod.Edge,
                        InterpolationMethod.NearestNeighbour);
                    var x2 = new ColorArrayFloat(100, 100, OverlayMethod.Edge,
                        InterpolationMethod.NearestNeighbour);

                    Assert.AreNotEqual(x1, x2);
                }
                {
                    var x1 = new ColorArrayFloat(100, 100, OverlayMethod.Mirror,
                        InterpolationMethod.NearestNeighbour);
                    var x2 = new ColorArrayFloat(100, 100, OverlayMethod.Edge,
                        InterpolationMethod.NearestNeighbour);

                    Assert.AreNotEqual(x1, x2);
                }
                {
                    var x1 = new ColorArrayFloat(100, 100, OverlayMethod.Edge,
                        InterpolationMethod.Bilinear);
                    var x2 = new ColorArrayFloat(100, 100, OverlayMethod.Edge,
                        InterpolationMethod.NearestNeighbour);

                    Assert.AreNotEqual(x1, x2);
                }
            }

            string file = "small_for_test1.bmp";

            {
                {
                    var x1 = new ColorArrayFloatFile(file, a_overlayMethod: OverlayMethod.Edge, a_interpolationMethod: InterpolationMethod.NearestNeighbour);
                    var x2 = new ColorArrayFloatFile(file, a_overlayMethod: OverlayMethod.Edge, a_interpolationMethod: InterpolationMethod.NearestNeighbour);

                    Assert.AreEqual(x1, x2);
                }
                {
                    var x1 = new ColorArrayFloatFile(file, a_overlayMethod: OverlayMethod.Mirror, a_interpolationMethod: InterpolationMethod.NearestNeighbour);
                    var x2 = new ColorArrayFloatFile(file, a_overlayMethod: OverlayMethod.Edge, a_interpolationMethod: InterpolationMethod.NearestNeighbour);

                    Assert.AreNotEqual(x1, x2);
                }
                {
                    var x1 = new ColorArrayFloatFile(file, a_overlayMethod: OverlayMethod.Edge, a_interpolationMethod: InterpolationMethod.NearestNeighbour);
                    var x2 = new ColorArrayFloatFile(file, a_overlayMethod: OverlayMethod.Edge, a_interpolationMethod: InterpolationMethod.Bilinear);

                    Assert.AreNotEqual(x1, x2);
                }
            }
            {
                {
                    var x1 = new ColorArrayFloat(100, 100, OverlayMethod.Edge,
                        InterpolationMethod.NearestNeighbour);
                    var x2 = new ColorArrayFloat(100, 100, OverlayMethod.Edge,
                        InterpolationMethod.NearestNeighbour);

                    Assert.AreEqual(x1, x2);
                }
                {
                    var x1 = new ColorArrayFloat(99, 100, OverlayMethod.Edge,
                        InterpolationMethod.NearestNeighbour);
                    var x2 = new ColorArrayFloat(100, 100, OverlayMethod.Edge,
                        InterpolationMethod.NearestNeighbour);

                    Assert.AreNotEqual(x1, x2);
                }
                {
                    var x1 = new ColorArrayFloat(100, 99, OverlayMethod.Edge,
                        InterpolationMethod.NearestNeighbour);
                    var x2 = new ColorArrayFloat(100, 100, OverlayMethod.Edge,
                        InterpolationMethod.NearestNeighbour);

                    Assert.AreNotEqual(x1, x2);
                }
                {
                    var x1 = new ColorArrayFloat(100, 100, OverlayMethod.Mirror,
                        InterpolationMethod.NearestNeighbour);
                    var x2 = new ColorArrayFloat(100, 100, OverlayMethod.Edge,
                        InterpolationMethod.NearestNeighbour);

                    Assert.AreNotEqual(x1, x2);
                }
                {
                    var x1 = new ColorArrayFloat(100, 100, OverlayMethod.Edge,
                        InterpolationMethod.Bilinear);
                    var x2 = new ColorArrayFloat(100, 100, OverlayMethod.Edge,
                        InterpolationMethod.NearestNeighbour);

                    Assert.AreNotEqual(x1, x2);
                }
            }
            {
                {
                    var x1 = new ValueArrayFloat(100, 100, OverlayMethod.Edge,
                        InterpolationMethod.NearestNeighbour);
                    var x2 = new ValueArrayFloat(100, 100, OverlayMethod.Edge,
                        InterpolationMethod.NearestNeighbour);

                    Assert.AreEqual(x1, x2);
                }
                {
                    var x1 = new ValueArrayFloat(99, 100, OverlayMethod.Edge,
                        InterpolationMethod.NearestNeighbour);
                    var x2 = new ValueArrayFloat(100, 100, OverlayMethod.Edge,
                        InterpolationMethod.NearestNeighbour);

                    Assert.AreNotEqual(x1, x2);
                }

                {
                    var x1 = new ValueArrayFloat(100, 99, OverlayMethod.Edge,
                        InterpolationMethod.NearestNeighbour);
                    var x2 = new ValueArrayFloat(100, 100, OverlayMethod.Edge,
                        InterpolationMethod.NearestNeighbour);

                    Assert.AreNotEqual(x1, x2);
                }
                {
                    var x1 = new ValueArrayFloat(100, 100, OverlayMethod.Mirror,
                        InterpolationMethod.NearestNeighbour);
                    var x2 = new ValueArrayFloat(100, 100, OverlayMethod.Edge,
                        InterpolationMethod.NearestNeighbour);

                    Assert.AreNotEqual(x1, x2);
                }
                {
                    var x1 = new ValueArrayFloat(100, 100, OverlayMethod.Edge,
                        InterpolationMethod.Bilinear);
                    var x2 = new ValueArrayFloat(100, 100, OverlayMethod.Edge,
                        InterpolationMethod.NearestNeighbour);

                    Assert.AreNotEqual(x1, x2);
                }
                {
                    var x1 = new ValueArrayFloat(100, 100, OverlayMethod.Edge,
                        InterpolationMethod.NearestNeighbour);
                    var x2 = new ValueArrayFloat(100, 100, OverlayMethod.Edge,
                        InterpolationMethod.NearestNeighbour);

                    x1.SetValue(0, 0, 0.1);

                    Assert.AreNotEqual(x1, x2);
                }
            }
            {
                var x1 = new ValueArrayFloatFile(file, OverlayMethod.Edge,
                    InterpolationMethod.NearestNeighbour);
                var x2 = new ValueArrayFloatFile(file, OverlayMethod.Edge,
                    InterpolationMethod.NearestNeighbour);

                Assert.AreEqual(x1, x2);
            }
            {
                var x1 = new ValueArrayFloatFile(file, OverlayMethod.Mirror,
                    InterpolationMethod.NearestNeighbour);
                var x2 = new ValueArrayFloatFile(file, OverlayMethod.Edge,
                    InterpolationMethod.NearestNeighbour);

                Assert.AreNotEqual(x1, x2);
            }
            {
                var x1 = new ValueArrayFloatFile(file, OverlayMethod.Edge,
                    InterpolationMethod.NearestNeighbour);
                var x2 = new ValueArrayFloatFile(file, OverlayMethod.Edge,
                    InterpolationMethod.Bilinear);

                Assert.AreNotEqual(x1, x2);
            }
            {
                {
                    var x1 = new ValueArrayFloat(100, 100, OverlayMethod.Edge,
                        InterpolationMethod.NearestNeighbour);
                    var x2 = new ValueArrayFloat(100, 100, OverlayMethod.Edge,
                        InterpolationMethod.NearestNeighbour);

                    Assert.AreEqual(x1, x2);
                }
                {
                    var x1 = new ValueArrayFloat(99, 100, OverlayMethod.Edge,
                        InterpolationMethod.NearestNeighbour);
                    var x2 = new ValueArrayFloat(100, 100, OverlayMethod.Edge,
                        InterpolationMethod.NearestNeighbour);

                    Assert.AreNotEqual(x1, x2);
                }
                {
                    var x1 = new ValueArrayFloat(100, 99, OverlayMethod.Edge,
                        InterpolationMethod.NearestNeighbour);
                    var x2 = new ValueArrayFloat(100, 100, OverlayMethod.Edge,
                        InterpolationMethod.NearestNeighbour);

                    Assert.AreNotEqual(x1, x2);
                }
                {
                    var x1 = new ValueArrayFloat(100, 100, OverlayMethod.Mirror,
                        InterpolationMethod.NearestNeighbour);
                    var x2 = new ValueArrayFloat(100, 100, OverlayMethod.Edge,
                        InterpolationMethod.NearestNeighbour);

                    Assert.AreNotEqual(x1, x2);
                }
                {
                    var x1 = new ValueArrayFloat(100, 100, OverlayMethod.Edge,
                        InterpolationMethod.Bilinear);
                    var x2 = new ValueArrayFloat(100, 100, OverlayMethod.Edge,
                        InterpolationMethod.NearestNeighbour);

                    Assert.AreNotEqual(x1, x2);
                }
                {
                    var x1 = new ValueArrayFloat(100, 100, OverlayMethod.Edge,
                        InterpolationMethod.NearestNeighbour);
                    var x2 = new ValueArrayFloat(100, 100, OverlayMethod.Edge,
                        InterpolationMethod.NearestNeighbour);

                    x1.SetValue(0, 0, 0.1);

                    Assert.AreNotEqual(x1, x2);
                }
            }

            {
                {
                    var x1 = new ValueArrayFloat(100, 100, OverlayMethod.Edge,
                        InterpolationMethod.NearestNeighbour);
                    var x2 = new ValueArrayFloat(100, 100, OverlayMethod.Edge,
                        InterpolationMethod.NearestNeighbour);

                    x1.TangentsPixelDelta = 1;
                    x2.TangentsPixelDelta = 2;

                    Assert.AreNotEqual(x1, x2);
                }

                {
                    var x1 = new ColorArrayFloat(100, 100, OverlayMethod.Edge,
                        InterpolationMethod.NearestNeighbour);
                    var x2 = new ColorArrayFloat(100, 100, OverlayMethod.Edge,
                        InterpolationMethod.NearestNeighbour);

                    x1.TangentsPixelDelta = 1;
                    x2.TangentsPixelDelta = 2;

                    Assert.AreNotEqual(x1, x2);
                }

                {
                    var x1 = new ValueArrayFloat(100, 100, OverlayMethod.Edge,
                        InterpolationMethod.NearestNeighbour);
                    var x2 = new ValueArrayFloat(100, 100, OverlayMethod.Edge,
                        InterpolationMethod.NearestNeighbour);

                    x1.TangentsScale = 1;
                    x2.TangentsScale = 2;

                    Assert.AreNotEqual(x1, x2);
                }

                {
                    var x1 = new ColorArrayFloat(100, 100, OverlayMethod.Edge,
                        InterpolationMethod.NearestNeighbour);
                    var x2 = new ColorArrayFloat(100, 100, OverlayMethod.Edge,
                        InterpolationMethod.NearestNeighbour);

                    x1.TangentsScale = 1;
                    x2.TangentsScale = 2;

                    Assert.AreNotEqual(x1, x2);
                }
            }
        }

        public void Arrays_SetX_GetBitmap_GetArray()
        {
            Color c1 = Color.FromArgb(23, 34, 135);
            Color c2 = Color.FromArgb(24, 35, 136);
            Color c3 = Color.FromArgb(25, 36, 137);

            string file = "small_for_test1.bmp";

            {
                var x1 = new ColorArrayFloatFile(file);

                Bitmap bmp = x1.GetBitmap();

                Assert.IsTrue(bmp.GetPixel(0, 0) == Color.FromArgb(133, 96, 53));
                Assert.IsTrue(bmp.GetPixel(29, 40) == Color.FromArgb(170, 122, 66));
                Assert.IsTrue(bmp.GetPixel(x1.Width - 1, x1.Height - 1) ==
                    Color.FromArgb(127, 79, 35));

                bmp = x1.GetBitmap(new Rectangle(23, 24, 50, 51));
                Assert.AreEqual(bmp.Width, 50);
                Assert.AreEqual(bmp.Height, 51);
                Assert.IsTrue(bmp.GetPixel(29 - 23, 40 - 24) ==
                    Color.FromArgb(170, 122, 66));

                ColorArrayFloat array = x1.GetArrayRect(new Rectangle(23, 24, 50, 51));
                Assert.AreEqual(array.Width, 50);
                Assert.AreEqual(array.Height, 51);
                Assert.IsTrue(Gamma.LinearToSRGB(array[29 - 23, 40 - 24]).SystemColor ==
                    Color.FromArgb(170, 122, 66));
            }

            double v1 = 0.45;
            double v2 = 0.78;
            double v3 = 0.96;

            double v11 = (0.45 * 255).Round() / 255.0;
            double v21 = (0.78 * 255).Round() / 255.0;
            double v31 = (0.96 * 255).Round() / 255.0;

            {
                var x1 = new ValueArrayFloat(100, 120);

                x1.SetValue(0, 0, v1);
                Assert.IsTrue(x1.GetValue(0, 0).IsAlmostEquals(v1, Constants.COLOR_PRECISION));

                x1.SetValue(29, 40, v2);
                Assert.IsTrue(x1.GetValue(29, 40).IsAlmostEquals(v2, Constants.COLOR_PRECISION));

                x1.SetValue(99, 119, v3);
                Assert.IsTrue(x1.GetValue(99, 119).IsAlmostEquals(v3, Constants.COLOR_PRECISION));

                Bitmap bmp = x1.GetBitmap();

                Assert.IsTrue(bmp.GetPixel(0, 0) == new ColorFloat(v11).SystemColor);
                Assert.IsTrue(bmp.GetPixel(29, 40) == new ColorFloat(v21).SystemColor);
                Assert.IsTrue(bmp.GetPixel(99, 119) == new ColorFloat(v31).SystemColor);

                bmp = x1.GetBitmap(new Rectangle(23, 24, 50, 51));
                Assert.AreEqual(bmp.Width, 50);
                Assert.AreEqual(bmp.Height, 51);
                Assert.IsTrue(bmp.GetPixel(29 - 23, 40 - 24) ==
                    new ColorFloat(v21).SystemColor);

                ValueArrayFloat array = x1.GetArrayRect(new Rectangle(23, 24, 50, 51));
                Assert.AreEqual(array.Width, 50);
                Assert.AreEqual(array.Height, 51);
                Assert.IsTrue(array.GetColor(29 - 23, 40 - 24).SystemColor ==
                    new ColorFloat(v21).SystemColor);
            }

            {
                var x1 = new ValueArrayFloatFile(file);

                Bitmap bmp = x1.GetBitmap();

                Assert.IsTrue(bmp.GetPixel(0, 0) == Color.FromArgb(94, 94, 94));
                Assert.IsTrue(bmp.GetPixel(29, 40) == Color.FromArgb(119, 119, 119));
                Assert.IsTrue(bmp.GetPixel(x1.Width - 1, x1.Height - 1) ==
                    Color.FromArgb(80, 80, 80));

                bmp = x1.GetBitmap(new Rectangle(23, 24, 50, 51));
                Assert.AreEqual(bmp.Width, 50);
                Assert.AreEqual(bmp.Height, 51);
                Assert.IsTrue(bmp.GetPixel(29 - 23, 40 - 24) ==
                    Color.FromArgb(119, 119, 119));

                ValueArrayFloat array = x1.GetArrayRect(new Rectangle(23, 24, 50, 51));
                Assert.AreEqual(array.Width, 50);
                Assert.AreEqual(array.Height, 51);
                Assert.IsTrue(array.GetColor(29 - 23, 40 - 24).SystemColor ==
                    Color.FromArgb(119, 119, 119));
            }
        }

        public void Arrays_Create()
        {
            Color t1 = Color.FromArgb(12, 13, 114);
            Color t2 = Color.FromArgb(22, 23, 124);
            Color t3 = Color.FromArgb(32, 33, 134);
            Bitmap bmp = new Bitmap(100, 120);
            bmp.SetPixel(0, 0, t1);
            bmp.SetPixel(80, 110, t2);
            bmp.SetPixel(99, 119, t3);

            Func<Color, double> avg1 = (color) =>
            {
                return (color.R + color.G + color.B) / 3 / 255.0;
            };

            Func<Color, double> avg2 = (color) =>
            {
                return (color.R / 255.0 + color.G / 255.0 + color.B / 255.0) / 3.0;
            };

            string file = "small_for_test1.bmp";
            string filefull = PathResolver.GetTexturePath(file);
            Bitmap bmp1 = new Bitmap(filefull);

            {
                var x1 = new ColorArrayFloatFile(file, a_overlayMethod: OverlayMethod.Mirror, a_interpolationMethod: InterpolationMethod.NearestNeighbour);

                Assert.IsTrue(file == x1.FileName);
                Assert.IsTrue(x1.Width == bmp1.Width);
                Assert.IsTrue(x1.Height == bmp1.Height);
                Assert.IsTrue(x1.InterpolationMethod == InterpolationMethod.NearestNeighbour);
                Assert.IsTrue(x1.OverlayMethod == OverlayMethod.Mirror);
                Assert.IsTrue(Gamma.LinearToSRGB(x1.GetColor(0, 0)).SystemColor.Equals(bmp1.GetPixel(0, 0)));
                Assert.IsTrue(Gamma.LinearToSRGB(x1.GetColor(99, 119)).SystemColor.Equals(bmp1.GetPixel(99, 119)));
                Assert.IsTrue(Gamma.LinearToSRGB(x1.GetColor(x1.Width - 1, x1.Height - 1)).SystemColor.Equals(
                    bmp1.GetPixel(x1.Width - 1, x1.Height - 1)));
            }

            {
                var x1 = new ColorArrayFloat(bmp, OverlayMethod.Mirror,
                    InterpolationMethod.NearestNeighbour);

                Assert.IsTrue(x1.Width == 100);
                Assert.IsTrue(x1.Height == 120);
                Assert.IsTrue(x1.InterpolationMethod == InterpolationMethod.NearestNeighbour);
                Assert.IsTrue(x1.OverlayMethod == OverlayMethod.Mirror);
                Assert.IsTrue(Gamma.LinearToSRGB(x1.GetColor(0, 0)).SystemColor.Equals(t1));
                Assert.IsTrue(Gamma.LinearToSRGB(x1.GetColor(80, 110)).SystemColor.Equals(t2));
                Assert.IsTrue(Gamma.LinearToSRGB(x1.GetColor(99, 119)).SystemColor.Equals(t3));
            }

            {
                var x1 = new ColorArrayFloat(100, 120, OverlayMethod.Mirror,
                    InterpolationMethod.NearestNeighbour);

                Assert.IsTrue(x1.Width == 100);
                Assert.IsTrue(x1.Height == 120);
                Assert.IsTrue(x1.InterpolationMethod == InterpolationMethod.NearestNeighbour);
                Assert.IsTrue(x1.OverlayMethod == OverlayMethod.Mirror);
            }

            {
                var x1 = new ValueArrayFloatFile(file, OverlayMethod.Mirror,
                    InterpolationMethod.NearestNeighbour);

                Assert.IsTrue(file == x1.FileName);
                Assert.IsTrue(x1.Width == bmp1.Width);
                Assert.IsTrue(x1.Height == bmp1.Height);
                Assert.IsTrue(x1.InterpolationMethod == InterpolationMethod.NearestNeighbour);
                Assert.IsTrue(x1.OverlayMethod == OverlayMethod.Mirror);
                Assert.IsTrue(x1.GetValue(0, 0).IsAlmostEquals(avg1(bmp1.GetPixel(0, 0)), Constants.COLOR_PRECISION));
                Assert.IsTrue(x1.GetValue(99, 119).IsAlmostEquals(avg1(bmp1.GetPixel(99, 119)), Constants.COLOR_PRECISION));
                Assert.IsTrue(x1.GetValue(x1.Width - 1, x1.Height - 1).IsAlmostEquals(
                    avg2(bmp1.GetPixel(x1.Width - 1, x1.Height - 1)), Constants.COLOR_PRECISION));
            }

            {
                var x1 = new ValueArrayFloat(bmp, OverlayMethod.Mirror,
                    InterpolationMethod.NearestNeighbour);

                Assert.IsTrue(x1.Width == 100);
                Assert.IsTrue(x1.Height == 120);
                Assert.IsTrue(x1.InterpolationMethod == InterpolationMethod.NearestNeighbour);
                Assert.IsTrue(x1.OverlayMethod == OverlayMethod.Mirror);
                Assert.IsTrue(x1.GetValue(0, 0).IsAlmostEquals(avg2(t1), Constants.COLOR_PRECISION));
                Assert.IsTrue(x1.GetValue(80, 110).IsAlmostEquals(avg2(t2), Constants.COLOR_PRECISION));
                Assert.IsTrue(x1.GetValue(99, 119).IsAlmostEquals(avg2(t3), Constants.COLOR_PRECISION));
            }

            {
                var x1 = new ValueArrayFloat(100, 120, OverlayMethod.Mirror,
                    InterpolationMethod.NearestNeighbour);

                Assert.IsTrue(x1.Width == 100);
                Assert.IsTrue(x1.Height == 120);
                Assert.IsTrue(x1.InterpolationMethod == InterpolationMethod.NearestNeighbour);
                Assert.IsTrue(x1.OverlayMethod == OverlayMethod.Mirror);
            }
        }
    }
}